/*******************************************************************************
 * Copyright (c) 2007 - 2025 Maxprograms.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-v10.html
 *
 * Contributors:
 *     Maxprograms - initial API and implementation
 *******************************************************************************/

class DoubaoSettings {
    electron = require('electron');
    currentConfig: any = null;
    isTestingConnection: boolean = false;
    isRecording: boolean = false;
    voiceRecognition: any = null;

    constructor() {
        this.electron.ipcRenderer.send('get-theme');
        this.electron.ipcRenderer.on('set-theme', (event: Electron.IpcRendererEvent, theme: string) => {
            (document.getElementById('theme') as HTMLLinkElement).href = theme;
        });

        this.loadConfig();
        this.setupEventListeners();
    }

    private async loadConfig(): Promise<void> {
        try {
            const config = await this.electron.ipcRenderer.invoke('get-doubao-config');
            if (config) {
                this.currentConfig = config;
                (document.getElementById('appKeyInput') as HTMLInputElement).value = config.appKey || '';
                (document.getElementById('accessKeyInput') as HTMLInputElement).value = config.accessKey || '';
                (document.getElementById('urlInput') as HTMLInputElement).value = config.url || 'wss://openspeech.bytedance.com/api/v3/sauc/bigmodel';
                (document.getElementById('resourceIdInput') as HTMLInputElement).value = config.resourceId || 'volc.bigasr.sauc.duration';
                
                // 加载麦克风设备列表
                await this.loadMicrophoneDevices();
                
                // 设置选中的麦克风
                if (config.selectedMicrophoneId) {
                    (document.getElementById('microphoneSelect') as HTMLSelectElement).value = config.selectedMicrophoneId;
                }
                
                // 如果配置完整，启用语音演示按钮
                if (config.appKey && config.accessKey) {
                    this.enableVoiceDemo();
                }
            } else {
                // 即使没有配置也要加载麦克风设备列表
                await this.loadMicrophoneDevices();
            }
        } catch (error) {
            console.error('加载豆包配置失败:', error);
            // 发生错误时也尝试加载麦克风设备列表
            await this.loadMicrophoneDevices();
        }
    }

    private async loadMicrophoneDevices(): Promise<void> {
        try {
            console.log('开始加载麦克风设备列表...');
            
            // 请求麦克风权限
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            
            // 获取设备列表
            const devices = await navigator.mediaDevices.enumerateDevices();
            const audioInputs = devices.filter(device => device.kind === 'audioinput');
            
            console.log('找到', audioInputs.length, '个音频输入设备');
            
            const microphoneSelect = document.getElementById('microphoneSelect') as HTMLSelectElement;
            microphoneSelect.innerHTML = '';
            
            // 添加默认选项
            const defaultOption = document.createElement('option');
            defaultOption.value = '';
            defaultOption.textContent = '使用默认麦克风';
            microphoneSelect.appendChild(defaultOption);
            
            // 添加所有麦克风设备
            audioInputs.forEach((device, index) => {
                const option = document.createElement('option');
                option.value = device.deviceId;
                option.textContent = device.label || `麦克风 ${index + 1}`;
                microphoneSelect.appendChild(option);
            });
            
            // 释放stream
            stream.getTracks().forEach(track => track.stop());
            
            console.log('麦克风设备列表加载完成');
            
        } catch (error) {
            console.error('加载麦克风设备失败:', error);
            const microphoneSelect = document.getElementById('microphoneSelect') as HTMLSelectElement;
            microphoneSelect.innerHTML = '<option value="">无法获取麦克风设备列表</option>';
        }
    }

    private setupEventListeners(): void {
        // 保存配置
        (document.getElementById('saveConfigBtn') as HTMLButtonElement).addEventListener('click', () => {
            this.saveConfig();
        });

        // 取消按钮
        (document.getElementById('cancelBtn') as HTMLButtonElement).addEventListener('click', () => {
            this.electron.ipcRenderer.send('close-doubao-settings');
        });

        // 测试连接
        (document.getElementById('testConnectionBtn') as HTMLButtonElement).addEventListener('click', () => {
            this.testConnection();
        });

        // 语音演示
        (document.getElementById('voiceDemoBtn') as HTMLButtonElement).addEventListener('click', () => {
            this.toggleVoiceDemo();
        });

        // 刷新麦克风设备列表
        (document.getElementById('refreshMicBtn') as HTMLButtonElement).addEventListener('click', () => {
            this.loadMicrophoneDevices();
        });

        // 键盘事件
        document.addEventListener('keydown', (event: KeyboardEvent) => {
            if (event.code === 'Escape') {
                this.electron.ipcRenderer.send('close-doubao-settings');
            }
            if (event.code === 'Enter' || event.code === 'NumpadEnter') {
                this.saveConfig();
            }
        });

        // 输入变化时清除测试结果
        const inputs = document.querySelectorAll('.input-field');
        inputs.forEach(input => {
            input.addEventListener('input', () => {
                this.clearTestResults();
            });
        });
    }

    private async saveConfig(): Promise<void> {
        const appKey = (document.getElementById('appKeyInput') as HTMLInputElement).value.trim();
        const accessKey = (document.getElementById('accessKeyInput') as HTMLInputElement).value.trim();
        const url = (document.getElementById('urlInput') as HTMLInputElement).value.trim();
        const resourceId = (document.getElementById('resourceIdInput') as HTMLInputElement).value.trim();
        const selectedMicrophoneId = (document.getElementById('microphoneSelect') as HTMLSelectElement).value;

        if (!appKey || !accessKey) {
            this.showMessage('请填写完整的APP ID和Access Token', 'error');
            return;
        }

        const config = {
            appKey,
            accessKey,
            url,
            resourceId,
            selectedMicrophoneId
        };

        try {
            const result = await this.electron.ipcRenderer.invoke('save-doubao-config', config);
            if (result.success) {
                this.currentConfig = config;
                this.showMessage('豆包语音识别配置保存成功！', 'success');
                this.enableVoiceDemo();
            } else {
                this.showMessage('保存配置失败: ' + result.error, 'error');
            }
        } catch (error: any) {
            this.showMessage('保存配置失败: ' + error.message, 'error');
        }
    }

    private async testConnection(): Promise<void> {
        if (this.isTestingConnection) {
            return;
        }

        const appKey = (document.getElementById('appKeyInput') as HTMLInputElement).value.trim();
        const accessKey = (document.getElementById('accessKeyInput') as HTMLInputElement).value.trim();
        const url = (document.getElementById('urlInput') as HTMLInputElement).value.trim();

        if (!appKey || !accessKey) {
            this.showTestResult('请先填写APP ID和Access Token', 'error');
            return;
        }

        this.isTestingConnection = true;
        const testBtn = document.getElementById('testConnectionBtn') as HTMLButtonElement;
        const testStatus = document.getElementById('testStatus') as HTMLSpanElement;
        
        testBtn.disabled = true;
        testBtn.textContent = '连接中...';
        testStatus.textContent = '正在测试连接...';

        this.showTestResult('正在尝试连接豆包语音识别服务...', 'info');

        try {
            // 通过主进程测试WebSocket连接，支持自定义headers
            const result = await this.electron.ipcRenderer.invoke('test-doubao-connection', {
                url: url,
                appKey: appKey,
                accessKey: accessKey,
                resourceId: 'volc.bigasr.sauc.duration'
            });

            if (result.success) {
                this.showTestResult(result.message, 'success');
                testStatus.textContent = '连接测试成功';
            } else {
                this.showTestResult('连接测试失败: ' + result.error, 'error');
                testStatus.textContent = '连接测试失败';
            }

        } catch (error: any) {
            this.showTestResult('连接测试失败: ' + error.message, 'error');
            testStatus.textContent = '连接测试失败';
        } finally {
            this.isTestingConnection = false;
            testBtn.disabled = false;
            testBtn.textContent = '测试连接';
        }
    }

    private enableVoiceDemo(): void {
        const voiceBtn = document.getElementById('voiceDemoBtn') as HTMLButtonElement;
        const voiceStatus = document.getElementById('voiceStatus') as HTMLSpanElement;
        
        voiceBtn.disabled = false;
        voiceStatus.textContent = '点击开始语音识别演示';
    }

    private async toggleVoiceDemo(): Promise<void> {
        if (this.isRecording) {
            this.stopVoiceDemo();
        } else {
            await this.startVoiceDemo();
        }
    }

    private async startVoiceDemo(): Promise<void> {
        try {
            const voiceBtn = document.getElementById('voiceDemoBtn') as HTMLButtonElement;
            const voiceStatus = document.getElementById('voiceStatus') as HTMLSpanElement;
            const demoResult = document.getElementById('demoResult') as HTMLDivElement;

            this.isRecording = true;
            voiceBtn.classList.add('recording');
            voiceBtn.textContent = '🔴 停止录音';
            voiceStatus.textContent = '演示功能暂不可用，请在实际页面测试语音识别';
            
            demoResult.style.display = 'block';
            demoResult.textContent = '语音识别配置已保存，请在翻译编辑器、术语编辑等页面的输入框中点击🎤按钮测试语音识别功能。';

            // 3秒后自动停止
            setTimeout(() => {
                this.stopVoiceDemo();
            }, 3000);

        } catch (error: any) {
            this.showMessage('语音识别演示失败: ' + error.message, 'error');
            this.stopVoiceDemo();
        }
    }

    private stopVoiceDemo(): void {
        try {
            this.isRecording = false;
            const voiceBtn = document.getElementById('voiceDemoBtn') as HTMLButtonElement;
            const voiceStatus = document.getElementById('voiceStatus') as HTMLSpanElement;

            voiceBtn.classList.remove('recording');
            voiceBtn.textContent = '🎤 开始录音';
            voiceStatus.textContent = '点击开始语音识别演示';
        } catch (error) {
            console.error('停止语音演示失败:', error);
        }
    }

    private showTestResult(message: string, type: 'success' | 'error' | 'info'): void {
        const testResult = document.getElementById('testResult') as HTMLDivElement;
        testResult.style.display = 'block';
        testResult.textContent = message;
        testResult.className = 'test-result test-' + type;
    }

    private clearTestResults(): void {
        const testResult = document.getElementById('testResult') as HTMLDivElement;
        testResult.style.display = 'none';
    }

    private showMessage(message: string, type: 'success' | 'error'): void {
        this.electron.ipcRenderer.send('show-message', {
            type: type === 'success' ? 'info' : 'error',
            message: message,
            parent: 'doubaoSettings'
        });
    }

    private generateUUID(): string {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }
} 